"use strict";
import DataProxy from './DataProxy.js';

var DirectiveRE = {
    "for": /wx:for/,
    "if": /wx:if/,

}

//----- VNode -----
export function VNode(type, tag, attrs) {
    // element
    this.tag = tag;
    this.type = type;
    this.attrs = attrs || {};

    // text
    this.text = null;

    // tree
    this.parent = null;
    this.children = [];
}

VNode.Type = {
    None: 0,
    Element: 1,
    Text: 3,
};

VNode.prototype.addChild = function (node) {
    node.parent = this;
    this.children.push(node);
};

VNode.prototype.getChild = function (index) {
    return this.children[index];
};

VNode.prototype.getChildCount = function () {
    return this.children.length;
};

VNode.printTree = function (vnode) {


};



//----- creator -----

function VTreeCreator(data) {

    this.dataProxy = new DataProxy([data,
        {
        _createElementNode: this._createElementNode,
        _createTextNode: this._createTextNode,
        _clist : this._clist,
        _expr: this._expr,
    }]);
}

VTreeCreator.prototype._createElementNode = function (tag, attrs, children) {

    var node = new VNode(VNode.Type.Element, tag, attrs);

    children = children || [];
    children.forEach(function (child) {
        if (Array.isArray(child)) {
            //for directive can return an array of elements
            child.forEach(function (item) {
                node.addChild(item);
            });
        }
        else {
            node.addChild(child);
        }
    });
    return node;
};

VTreeCreator.prototype._createTextNode = function (text) {
    var node = new VNode(VNode.Type.Text, null, null);
    node.text = text;
    return node;
};

VTreeCreator.prototype._clist = function (array, callback) {
    var nodes = [];
    array.forEach(function (item) {
        var node = callback(item);
        nodes.push(node);
    });
    return nodes;
};

VTreeCreator.prototype._expr = function (exp) {
    //todo: split exp and recusive get from data proxy

    exp = "with(this) { return (" + exp + "); }";
    var func = new Function(exp);
    var ret = func.apply(this);
    return ret;
};

VTreeCreator.prototype.create = function (code) {

    var root = null;
    try {
        code = 'with(this) {\nreturn (' + code + " )}";
        var func = new Function(code);
        root = func.apply(this.dataProxy);
    }
    catch (e) {
        console.warn(e.message);
    }

    return root;
};

export function createVNodeByCode(data, code) {

    var creator = new VTreeCreator(data);
    var root = creator.create(code);
    return root;
}